﻿using Furion.DependencyInjection;
using Furion.RemoteRequest;
using Furion.RemoteRequest.Extensions;
using FurStudy.Core;
using MySqlX.XDevAPI.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Application
{
    /// <summary>
    /// 发送远程请求
    /// 定义代理请求的接口并继承IHttpDispatchProxy接口
    /// </summary>
    [RetryPolicy(3, 1000)] // 支持全局
    public interface IHttp : IHttpDispatchProxy
    {
        [Get("https://www.furion.pro/get")]
        Task<Result> GetXXXAsync();

        [Post("https://www.furion.pro/post")]
        Task<Result> PostXXXAsync();

        /// <summary>
        /// 支持模板配置
        /// 模板格式为：#(配置路径)
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [Post("#(Furion:Address)/upload"), RetryPolicy(3, 1000)] // 支持局部
        Task<HttpRequestMessage> PostXXXAsync([Body] User user);

        //{
        //  "Furion": {
        //    "Address": "https://www.furion.pro"
        //  }
        //}

        // 注：方法的优先级高于接口定义的优先级

        [Put("https://www.furion.pro/put")]
        Task<Result> PutXXXAsync();

        [Delete("https://www.furion.pro/delete")]
        Task<Result> DeleteXXXAsync();

        [Patch("https://www.furion.pro/patch")]
        Task<Result> PatchXXXAsync();

        [Head("https://www.furion.pro/head")]
        Task<Result> HeadXXXAsync();

        // 使用命名客户端的配置

        /// <summary>
        /// 在代理请求中使用
        /// </summary>
        /// <returns></returns>
        [Get("api/getdata"), Client("github")]
        Task<User> GetData();

        /// <summary>
        /// 在字符串拓展使用
        /// 设置请求拦截
        /// </summary>
        /// <returns></returns>
        public async Task SetRuestInterceptionAsync()
        {
            var response = await "http://47.100.247.61/api/sysdata/categories".SetClient("github").PostAsync();
        }

        /// <summary>
        /// 关于返回值非200时忽略Http状态
        /// 特别说明：如果不加OnException，则会直接截断。 如果需要复杂的Http Post请求，建议直接使用PostAsync,返回值为HttpResponseMessage，可以更灵活的控制结果
        /// </summary>
        public async void ReturnIgnoreHttpStatus()
        {
            // 请求并且序列化请求结果
            var result = await "https://api.facebook.com/"
                // 如果不加OnException，则会直接截断
                .OnException((res, errors) =>
            {
                // 激活异步拦截 此处可以做记录日志操作 也可保持现状

            }).PostAsAsync<User>(); // PostAsStringAsync()也使用同样的OnException操作使得忽略返回Http状态,原样返回Http请求结果
        }

        /// <summary>
        /// 多线程共享作用域
        /// </summary>
        public void MultithreadedSharedScope()
        {
            Scoped.Create(async (fac, scope) => {
                var response = await "https://www.furion.pro".SetRequestScoped(scope.ServiceProvider).PostAsync();
            });
        }

        /// <summary>
        /// 静态Default方式构建
        /// </summary>
        public async void BuildStaticMode()
        {
            await HttpRequestPart.Default.SetRequestUrl("https://www.baidu.com").GetAsStringAsync();
        }
    }
}
